import BaseContext from '../../context';
/**
 * @class dom元素视窗交叉监听
 * @description dom元素出现在视窗内触发加载逻辑
 * @constructor
 */

export default class ChapterObserver extends BaseContext {
  constructor(app, options = {}) {
    super(app, options);

    this.intersectionObserver = null;
    this.observe = Object.assign({
      rootMargin: '100px 50px 100px 50px',
      threshold: [0, 0.25, 0.5, 0.75, 1] // 设定与跟元素交叉点
    }, this.options.abserve); // 上下预加载章节图片数量
    this.entryQueue = []; // 视窗队列
    this.intersectingList = []
    // 快速拖动忽略周期(忽略掉快速拖动过程中进入视窗的元素加载)
    this.duration = options.duration || 200;
    this.timer = null;
    this.init();
  }

  init() {
    const TAG = `初始化${this.constructor.name}`;
    const { logger } = this;
    logger.time(TAG);
    this.initObserver();
    this.listener({
      startImageObserver: this.startImageObserver.bind(this)
    });
    logger.timeEnd(TAG);
  }
  /**
   * @function initObserver 初始化监听
   * @return 无
   */
  initObserver() {
    this.intersectionObserver = new IntersectionObserver(entries => {
      this.logger.time('执行一次观察加载耗时');
      entries.forEach((entry) => {
        const { target, isIntersecting } = entry;
        // 从监听dom上获取数据
        const { chapterId, chapterIndex } = this.util.getChapterDataset(target);
        const index = this.entryQueue.findIndex(item => {
          return item.chapterId === chapterId && item.chapterIndex === chapterIndex;
        });
        // 在可视范围
        if (isIntersecting) {
          // 不在列队中
          if (index === -1) {
            this.entryQueue.push({ target, chapterIndex, chapterId });
          }
          // 不在可视范围，将其剔除列队
        } else {
          // 已在列队中，不再推入列队
          if (index > -1) {
            this.entryQueue.splice(index, 1);
            this.logger.log(`已经在加载队列中了${chapterIndex}/${chapterId}`);
          }
        }
      });
      // 可见区域的targets
      this.emit('intersectingTargets', this.entryQueue);
      // 可见区域图片懒加载
      this.lazyImagesObserver(this.entryQueue);
      this.logger.timeEnd('执行一次观察加载耗时');
    }, this.observe);
  }


  /**
   * @function lazyImagesObserver 执行懒加载观察图片
   * @return 无
   */
  lazyImagesObserver(entryQueue) {
    // 发送加载图片队列
    if (this.timer) {
      clearTimeout(this.timer);
    }
    this.timer = setTimeout(() => {
      const loadImages = [];
      const { chapterMap } = this.comicInfo;
      entryQueue.forEach(({ target, chapterIndex, chapterId }) => {
        const { chapterList } = chapterMap[chapterId];
        const image = chapterList[chapterIndex - 1];
        image.target = target;
        // 没有加载过图片，需要加入队列加载图片，已经加载过图片则需要取消监听
        if (image.status === 'init') {
          loadImages.push(image);
        } else {
          // 取消监听
          // this.intersectionObserver.unobserve(target);
        }
      });
      if (loadImages.length) {
        // 发送加载图片队列
        this.emit('loadImages', loadImages);
      }
    }, this.duration);
  }

  /**
   * @function startImageObserver 开启元素视窗监听
   * @param {array} doms 图片dom列表
   * @return 无
   */
  startImageObserver(doms = []) {
    // 将doms转换成可迭代数组
    doms = [].slice.call(doms);
    doms.forEach(dom => {
      this.intersectionObserver.observe(dom);
    })
  }
}
